package com.gwz.wxtime.chessboard.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.gwz.wxtime.core.consts.RedisKeyConst;
import com.gwz.wxtime.core.entity.base.BaseDTO;
import com.gwz.wxtime.core.entity.wx.GroupReceiveMessage;
import com.gwz.wxtime.core.entity.wx.MessageChildHistory;
import com.gwz.wxtime.core.entity.wx.MessageHistory;
import com.gwz.wxtime.core.service.BaseService;
import com.gwz.wxtime.core.util.GPT2Tokenizer;
import com.gwz.wxtime.core.util.IpUtil;
import com.gwz.wxtime.core.util.WxUtil;
import com.gwz.wxtime.openai.com.theokanning.openai.OpenAiApi;
import com.gwz.wxtime.openai.com.theokanning.openai.completion.ChatCompletionRequest;
import com.gwz.wxtime.openai.com.theokanning.openai.completion.ChatRoleChat;
import com.gwz.wxtime.openai.com.theokanning.openai.genImg.ImgRequest;
import com.gwz.wxtime.openai.com.theokanning.openai.genImg.ImgResponse;
import com.plexpt.chatgpt.ChatGPT;
import com.plexpt.chatgpt.entity.chat.ChatCompletion;
import com.plexpt.chatgpt.entity.chat.Message;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Order(99999)
@Slf4j
public class TuLingService implements BaseService {


    @Autowired
    OpenAiApi openAiApi;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private GPT2Tokenizer gpt2Tokenizer;


    private int answerToken = 1000;
    private int groupAnswerToken = 1000;
    private int maxToken = 4097 - answerToken;
    private int maxTokenGroup = 4097 - groupAnswerToken;

    //private String endToken = "'<|im_end|>";
    private String endToken = "";
    //private String separatorToken = "'<|im_sep|>";
    private String separatorToken = "";

    private String model = "gpt-3.5-turbo-0301";
    private String chatGptLabel = "小时间";
    private String userLabel = "主人";

    //private String promptSuffix = chatGptLabel + ":\n";
    private String promptSuffix = "";
    @Value("${chatGpt.key}")
    private String token;

    @Override

    public boolean handGroupReceivedMessage(BaseDTO<BaseDTO<GroupReceiveMessage>> dto) throws InterruptedException {
      /*  if (CollUtil.newArrayList(dto.getData().getData().getAtWxidList()).contains(WxUtil.wxId)|| dto.getData().getData().getMsg().contains("@小时间")) {
            String msg = dto.getData().getData().getMsg().replace("@时间 ", "");
            msg = msg.replace("@我是机器人 ", "");
            msg = msg.replace("@机器人vip版内部专用 ", "");
            msg = msg.replace("@小时间 ", "");
            msg = msg.trim();

            String replay = getReplay(dto.getData().getData().getFinalFromWxid(), msg, dto.getData().getData().getFromWxid());

            return true;

        }*/

        String oldMessage = new String(dto.getData().getData().getMsg());
        String msg = dto.getData().getData().getMsg().replace("@时间 ", "");
        msg = msg.replace("@我是机器人 ", "");
        msg = msg.replace("@机器人vip版内部专用 ", "");
        msg = msg.replace("@小时间 ", "");
        msg = msg.trim();
        getGroupReplay(dto.getData().getData().getFinalFromWxid(), msg, dto.getData().getData().getFromWxid(), dto.getData().getData().getAtWxidList(), oldMessage);
        return false;
    }


    @Override
    public boolean handPrivateChatSingleReceivedMessage(BaseDTO<BaseDTO<GroupReceiveMessage>> dto) throws InterruptedException {
        String msg = dto.getData().getData().getMsg();
        msg = msg.trim();

        getReplay(dto.getData().getData().getFromWxid(), msg, dto.getData().getData().getFromWxid());
        return true;
    }


    private synchronized String getGroupReplay(String finalWxid, String msg, String fromWxid, String[] atWxidList, String oldMessage) {

        log.info("消息:{}", msg);

        if (msg.startsWith("生成图片")) {
            msg = msg.replaceFirst("生成图片", "").trim();
            ImgRequest imgRequest = ImgRequest.builder().prompt(msg).user(finalWxid).n(1).size("256x256").response_format("url").build();
            log.info("生成图片请求:{}", imgRequest);

            ImgResponse imgResponse = openAiApi.generationsImage(imgRequest);
            log.info("生成图片响应:{}", imgResponse);

            String url = imgResponse.getData().get(0).getUrl();
            String path = "C:\\Users\\Administrator\\Desktop\\data" + File.separator + UUID.randomUUID().toString() + ".png";
            HttpUtil.downloadFile(url, path);
            WxUtil.sendImage(fromWxid, path);

            return url;
        }

        if (msg.contains("清除记忆")) {
            MessageHistory groupMessageHistory = getGroupMessageHistory(fromWxid);
            groupMessageHistory.setChats(new ArrayList<>());
            setGroupMessageHistory(fromWxid, groupMessageHistory);

            WxUtil.sendMessage(fromWxid, "已清除");

            return "";
        } else if (msg.contains("高冷模式")) {
            log.info("高冷模式进入");
            WxUtil.sendMessage(fromWxid, "已进入高冷模式");
            MessageHistory groupMessageHistory = getGroupMessageHistory(fromWxid);
            groupMessageHistory.setCharacter(0);


            String nickNames = getNickNames(groupMessageHistory.getChats());
            String buildGroupPromptPrefix = buildGroupPromptPrefix(nickNames, groupMessageHistory.getCharacter());
            String groupPromptSuffix = buildGroupPromptSuffix(groupMessageHistory.getCharacter());
            groupMessageHistory.setGroupPromptPrefix(buildGroupPromptPrefix);
            groupMessageHistory.setGroupPromptSuffix(groupPromptSuffix);

            setGroupMessageHistory(fromWxid, groupMessageHistory);
            return "";
        } else if (msg.contains("热情模式")) {
            log.info("热情模式进入");
            WxUtil.sendMessage(fromWxid, "已进入热情模式");
            MessageHistory groupMessageHistory = getGroupMessageHistory(fromWxid);
            groupMessageHistory.setCharacter(1);

            String nickNames = getNickNames(groupMessageHistory.getChats());
            String buildGroupPromptPrefix = buildGroupPromptPrefix(nickNames, groupMessageHistory.getCharacter());
            String groupPromptSuffix = buildGroupPromptSuffix(groupMessageHistory.getCharacter());
            groupMessageHistory.setGroupPromptPrefix(buildGroupPromptPrefix);
            groupMessageHistory.setGroupPromptSuffix(groupPromptSuffix);

            setGroupMessageHistory(fromWxid, groupMessageHistory);
            return "";
        } else if (msg.contains("正常模式")) {
            log.info("正常模式进入");
            WxUtil.sendMessage(fromWxid, "已进入正常模式");
            MessageHistory groupMessageHistory = getGroupMessageHistory(fromWxid);
            groupMessageHistory.setCharacter(2);

            String nickNames = getNickNames(groupMessageHistory.getChats());
            String buildGroupPromptPrefix = buildGroupPromptPrefix(nickNames, groupMessageHistory.getCharacter());
            String groupPromptSuffix = buildGroupPromptSuffix(groupMessageHistory.getCharacter());
            groupMessageHistory.setGroupPromptPrefix(buildGroupPromptPrefix);
            groupMessageHistory.setGroupPromptSuffix(groupPromptSuffix);

            setGroupMessageHistory(fromWxid, groupMessageHistory);
            return "";
        } else if (msg.contains("@模式") || msg.contains("艾特模式")) {
            MessageHistory groupMessageHistory = getGroupMessageHistory(fromWxid);
            groupMessageHistory.setIsForbiddenWords(1);
            setGroupMessageHistory(fromWxid, groupMessageHistory);
            WxUtil.sendMessage(fromWxid, "已进入艾特模式");
            return "";
        } else if (msg.equals("自动回复")) {
            MessageHistory groupMessageHistory = getGroupMessageHistory(fromWxid);
            groupMessageHistory.setIsForbiddenWords(2);
            setGroupMessageHistory(fromWxid, groupMessageHistory);
            WxUtil.sendMessage(fromWxid, "自动回复开启");

            return "";
        } else if (msg.equals("禁言") || msg.equals("闭嘴")) {
            MessageHistory groupMessageHistory = getGroupMessageHistory(fromWxid);
            groupMessageHistory.setIsForbiddenWords(3);
            setGroupMessageHistory(fromWxid, groupMessageHistory);
            WxUtil.sendMessage(fromWxid, "已禁言");

            return "";
        }


        String groupChatgptReplay = getGroupChatgptReplay(finalWxid, msg, fromWxid, atWxidList, oldMessage);
        if (!groupChatgptReplay.contains("none")
                && !groupChatgptReplay.contains("回复")
                && !groupChatgptReplay.contains("安静")
                && !groupChatgptReplay.contains("提醒")
                && !groupChatgptReplay.contains("明白了")
                && !groupChatgptReplay.contains("知道了")
                && !groupChatgptReplay.contains("注意的")
                && !groupChatgptReplay.contains("聊天记录")
                && !groupChatgptReplay.contains("None") && !groupChatgptReplay.contains("NONE")
                && !groupChatgptReplay.contains("沉默")) {

            if (groupChatgptReplay.contains(":")) {
                groupChatgptReplay = groupChatgptReplay.replace("小时间:", "");
                groupChatgptReplay = groupChatgptReplay.replace("昵称:小时间,", "");
                groupChatgptReplay = groupChatgptReplay.replace("昵称: 小时间,", "");
            }
            if (groupChatgptReplay.contains("：")) {
                groupChatgptReplay = groupChatgptReplay.replace("小时间：", "");
                groupChatgptReplay = groupChatgptReplay.replace("昵称：小时间,", "");
                groupChatgptReplay = groupChatgptReplay.replace("昵称： 小时间,", "");
            }
            WxUtil.sendMessage(fromWxid, groupChatgptReplay);
        }

        return null;
    }

    @NotNull
    private String getReplay(String wxId, String msg, String fromWxid) {

        if (msg.startsWith("生成图片")) {
            msg = msg.replaceFirst("生成图片", "").trim();
            ImgRequest imgRequest = ImgRequest.builder().prompt(msg).user(wxId).n(1).size("256x256").response_format("url").build();
            log.info("生成图片请求:{}", JSON.toJSONString(imgRequest));

            ImgResponse imgResponse = openAiApi.generationsImage(imgRequest);
            log.info("生成图片响应:{}", imgResponse);

            String url = imgResponse.getData().get(0).getUrl();
            String path = "C:\\Users\\Administrator\\Desktop\\data" + File.separator + UUID.randomUUID().toString() + ".png";
            HttpUtil.downloadFile(url, path);
            WxUtil.sendImage(fromWxid, path);

            return url;
        }


        String join = getChatgptReplay(wxId, msg);
        Character[] charsArray = join.chars().mapToObj(c -> (char) c).toArray(Character[]::new);

        ArrayList<Character> charList = ListUtil.toList(charsArray);

        List<List<Character>> partition = ListUtil.partition(charList, 500);


        for (List<Character> list : partition) {
            char[] chars = list.stream().map(Object::toString).collect(Collectors.joining()).toCharArray();
            String replay = String.valueOf(chars);


            WxUtil.sendMessage(fromWxid, replay);
        }

        return join;
    }

    @NotNull
    public synchronized String getGroupChatgptReplay(String userId, String msg, String fromWxid, String[] atWxidList, String oldMessage) {
        MessageHistory messageHistory = buildGroupPrompt(fromWxid, oldMessage, userId);

        String prompt = messageHistory.getChats().stream().map(Message::getContent).collect(Collectors.joining());


        Integer token = getToken(prompt);
        int max_tokens = Math.min(4097 - token, groupAnswerToken);

        ChatGPT chatgpt = ChatGPT
                .builder()
                .apiKeyList(ListUtil.toList(this.token.split(",")))
                .apiHost("https://oneapi.xty.app") //反向代理地址
                .build()
                .init();

        List<Message> chatRoleChats = messageHistory.getChats();

        ChatCompletion chatCompletion = ChatCompletion.builder()
                .model(ChatCompletion.Model.GPT_4.getName())
                .messages(chatRoleChats)
                .maxTokens(max_tokens)
                .temperature(0.7f)
                .topP(1)
                .user(userId)
                .build();

        /*    ChatCompletionRequest completionRequest = ChatCompletionRequest
                    .builder()
                    .model(model)
                    .messages(conversePrompt(messageHistory))
                    //.message(conversePrompt(messageHistory))
                    //.api_key(this.token)
                    .user(userId)
                    //.frequency_penalty(0)
                    // .presence_penalty(0)
                    .top_p(1)
                    //.stop(CollUtil.newArrayList(endToken, separatorToken))
                    .temperature(0.7f)
                    .max_tokens(max_tokens)
                    //.temperature(0.9f)
                    .build();*/


        String text = "none";
        try {
            if (messageHistory.getIsForbiddenWords() == 1) {
                if (CollUtil.newArrayList(atWxidList).contains(WxUtil.wxId) || oldMessage.contains("@小时间") || oldMessage.contains("@上海-小时间")) {
                    log.info("openai请求:{}", JSON.toJSONString(chatCompletion));
                    text = chatgpt.chatCompletion(chatCompletion).getChoices().get(0).getMessage().getContent();
                }
            } else if (messageHistory.getIsForbiddenWords() == 2) {
                log.info("openai请求:{}", JSON.toJSONString(chatCompletion));
                text = chatgpt.chatCompletion(chatCompletion).getChoices().get(0).getMessage().getContent();
            } else
                text = "none";
            //text = openAiApi.createChatCompletion(completionRequest).getChoices().get(0).getText();
        } catch (Exception e) {


            messageHistory.getChats().remove(0);
            messageHistory.getChats().remove(0);

            messageHistory.getChats().remove(messageHistory.getChats().size() - 1);
            setGroupMessageHistory(fromWxid, messageHistory);
            throw e;
        }


        // 去掉开头的系统
        messageHistory.getChats().remove(0);
        //去掉结尾
        messageHistory.getChats().remove(messageHistory.getChats().size() - 1);
        if (!text.contains("none")
                && !text.contains("回复")
                && !text.contains("安静")
                && !text.contains("聊天记录")
                && !text.contains("明白了")
                && !text.contains("注意的")
                && !text.contains("知道了")
                && !text.contains("提醒")
                && !text.contains("None") && !text.contains("NONE")
                && !text.contains("沉默")) {
            Message chatRoleChat = new Message();
            chatRoleChat.setRole("assistant");
            // chatRoleChat.setContent(StrUtil.format("[{}]:[{}]","小时间",text));


            if (!text.startsWith("小时间")) {
                text = "小时间:" + text;
            }
            if (CollUtil.isNotEmpty(messageHistory.getNickMaps())) {
                for (String nickMapKey : messageHistory.getNickMaps().keySet()) {
                    String value = messageHistory.getNickMaps().get(nickMapKey);
                    if (text.contains(value + ":")) {
                        text = text.replace(value + ":", "");
                    }
                    if (text.contains(value + "：")) {
                        text = text.replace(value + "：", "");
                    }
                }
                text = StrUtil.trimStart(text);
            }

            chatRoleChat.setContent(text);
            messageHistory.getChats().add(chatRoleChat);
        }


        setGroupMessageHistory(fromWxid, messageHistory);

        log.info("openai返回:{}", text);
        return text;
    }

    @NotNull
    public String getChatgptReplay(String userId, String msg) {
        String ip = IpUtil.getIpAddress(request);
        synchronized (ip) {

            MessageHistory messageHistory = buildPrompt(userId, msg);

            String prompt = messageHistory.getPromptPrefix() + messageHistory.getPromptBodyStr() + messageHistory.getPromptSuffix();

            Integer token = getToken(prompt);

            int max_tokens = Math.min(4097 - token, answerToken);

            log.info("最大token:{}, 消息token:{}", max_tokens, token);


            ChatGPT chatgpt = ChatGPT
                    .builder()
                    .apiKeyList(ListUtil.toList(this.token.split(",")))
                    .apiHost("https://oneapi.xty.app") //反向代理地址
                    .build()
                    .init();

            List<Message> chatRoleChats = conversePrompt(messageHistory);

            ChatCompletion chatCompletion = ChatCompletion.builder()
                    .model(ChatCompletion.Model.GPT_4.getName())
                    .messages(chatRoleChats)
                    .maxTokens(max_tokens)
                    .temperature(0.7f)
                    .topP(1)
                    .user(userId)
                    .build();

        /*    ChatCompletionRequest completionRequest = ChatCompletionRequest
                    .builder()
                    .model(model)
                    .messages(conversePrompt(messageHistory))
                    //.message(conversePrompt(messageHistory))
                    //.api_key(this.token)
                    .user(userId)
                    //.frequency_penalty(0)
                    // .presence_penalty(0)
                    .top_p(1)
                    //.stop(CollUtil.newArrayList(endToken, separatorToken))
                    .temperature(0.7f)
                    .max_tokens(max_tokens)
                    //.temperature(0.9f)
                    .build();*/
            log.info("openai请求:{}", JSON.toJSONString(chatCompletion));

            String text = "";
            try {
                //text = openAiApi.createChatCompletion(completionRequest).getChoices().get(0).getText();
                text = chatgpt.chatCompletion(chatCompletion).getChoices().get(0).getMessage().getContent();
            } catch (Exception e) {

                removeMessageHistory(userId);


                if (CollUtil.isNotEmpty(messageHistory.getPromptBody())) {
                    messageHistory.getPromptBody().remove(0);
                    setMessageHistory(userId, messageHistory);
                }
                throw e;
            }


            text = text.replace(endToken, "");


            MessageChildHistory lastMessageChildHistory = messageHistory.getPromptBody().get(messageHistory.getPromptBody().size() - 1);

            lastMessageChildHistory.setPromptAnswer(text);


            setMessageHistory(userId, messageHistory);

            log.info("openai返回:{}", text);


         /*   String[] split = text.split("\n");
            ArrayList<String> strings = CollUtil.newArrayList(split);
            strings.remove(0);
            String join = CollUtil.join(strings, "\n");
            if (join.startsWith("\n")) join = join.replaceFirst("\n", "");
            join = join.replace("\n\n", "\n");

            if (StrUtil.isBlank(join)) join = text;

            log.info("处理后text:{}", join);*/
            return text;
        }

    }


    private List<Message> conversePrompt(MessageHistory messageHistory) {
        // 因为要带上系统所以+1
        List<Message> chatRoleChats = new ArrayList<>(CollUtil.isEmpty(messageHistory.getPromptBody()) ? 0 : messageHistory.getPromptBody().size() + 1);

        Message systemChatRoleChat = new Message();
        systemChatRoleChat.setRole("system");
        systemChatRoleChat.setContent(messageHistory.getPromptPrefix());
        chatRoleChats.add(systemChatRoleChat);

        for (MessageChildHistory messageChildHistory : messageHistory.getPromptBody()) {

            Message userChatRoleChat = new Message();
            userChatRoleChat.setRole("user");
            userChatRoleChat.setContent(messageChildHistory.getPrompt());
            chatRoleChats.add(userChatRoleChat);

            if (messageChildHistory.getPromptAnswer() != null) {
                Message assistantChatRoleChat = new Message();
                assistantChatRoleChat.setRole("assistant");
                assistantChatRoleChat.setContent(messageChildHistory.getPromptAnswer());
                chatRoleChats.add(assistantChatRoleChat);
            }
        }
        return chatRoleChats;
    }


    private String buildPromptPrefix() {
        String promptPrefix = StrUtil.format("\n{}说明:\n我是一只叫{}的小猫,我是你的主人 说话喜欢带喵.\n 当前 日期: ${}${}\n\n", separatorToken, chatGptLabel, DateUtil.now(), separatorToken);
        return promptPrefix;
    }


    private String buildGroupPromptPrefix(String nickNames, Integer character) {
        switch (character) {
            case 0:
                return StrUtil.format("现在是在多人微信群聊里,群里有{},小时间, 当前 日期: {} ,assistant是其中一个叫小时间的群友,记住assistant叫小时间,小时间性格非常高冷 会根据性格决定回不回复,别人没喊assistant,assistant一定不会回复,如果你不回复会回复none,下面是聊天记录,聊天记录格式是 [昵称:说话内容], 请assistant继续接着聊天记录回复内容或回复none,如果回复内容一定简洁");
            case 1:
                return StrUtil.format("现在是在多人微信群聊里,群里有{},小时间, 当前 日期: {} ,assistant是其中一个叫小时间的群友,记住assistant叫小时间,小时间性格非常热情,会根据性格决定回不回复,别人没喊assistant,assistant一定不会回复,如果你不回复会回复none,下面是聊天记录,聊天记录格式是 [昵称:说话内容], 请assistant继续接着聊天记录回复内容或回复none,如果回复内容一定简洁");
            case 2:
                return StrUtil.format("现在是在多人微信群聊里,群里有{},小时间, 当前 日期: {} ,assistant是其中一个叫小时间的群友,记住assistant叫小时间,小时间性格有时高冷有时热情,会根据性格决定回不回复,有时会回复,有时不会回复,别人没喊assistant,assistant一定不会回复,如果assistant不回复会回复none,下面是聊天记录,聊天记录格式是 [昵称:说话内容], 请assistant继续接着聊天记录回复内容或回复none,如果回复内容一定简洁");
            default:
                return StrUtil.format("现在是在多人微信群聊里,群里有{},小时间, 当前 日期: {} ,assistant是其中一个叫小时间的群友,记住assistant叫小时间,小时间性格有时高冷有时热情,会根据性格决定回不回复,别人没喊assistant,assistant一定不会回复,如果assistant不回复会回复none,下面是聊天记录,聊天记录格式是 [昵称:说话内容], 请assistant继续接着聊天记录回复内容或回复none,如果回复内容一定简洁");
        }
    }


    private String buildGroupPromptSuffix(Integer character) {

        switch (character) {
            case 0:
                //return StrUtil.format("请记住 ,assistant现在在微信多人群聊里, assistant在群里是小时间,小时间性格非常高冷 ,请代替小时间接着聊天记录选择回复或不回复,会根据性格决定回不回复,不会代替其他人回复,如果回复直接回复内容,别人不喊assistant的名字,assistant会回复none, 如果回复内容 一定要简洁");
                return "";
            case 1:
                //return StrUtil.format("请记住 assistant是群里叫小时间的人 小时间性格热情, 不需要回复这句话,接着聊天记录回复,会根据性格决定回不回复,一定不代替别人回复,不回复请直接回复none,assistant在群里是小时间 ,请代替小时间接着聊天记录直接回复内容或回复none, 如果回复内容 一定要简洁");
                return "";

            case 2:
                //return StrUtil.format("请记住 assistant是群里叫小时间的人 小时间性格有时候热情,有时候高冷,会根据性格决定回不回复,一定不代替别人回复,不回复请直接回复none ,请代替小时间接着聊天记录直接回复内容或回复none, 如果回复内容 一定要简洁");
                return "";

            default:
                // return StrUtil.format("请记住 assistant是群里叫小时间的人 小时间性格有时候热情,有时候高冷, 接着聊天记录回复,会根据性格决定回不回复,一定不代替别人回复,不回复请直接回复none,assistant在群里是小时间 ,请代替小时间接着聊天记录直接回复内容或回复none, 如果回复内容 一定要简洁");
                return "";

        }
    }


    private MessageHistory buildPrompt(String conversationId, String msg) {
        String promptPrefix = buildPromptPrefix();


        MessageHistory messageHistory = getMessageHistory(conversationId);

        List<MessageChildHistory> messageChildHistories = new ArrayList<>();

        if (messageHistory != null && CollectionUtil.isNotEmpty(messageHistory.getPromptBody()))
            messageChildHistories = messageHistory.getPromptBody();


        MessageChildHistory messageChildHistory = new MessageChildHistory();
        messageChildHistory.setPrompt(msg);


        messageChildHistories.add(messageChildHistory);


        String promptBodyStr = buildPromptBody(messageChildHistories);


        //int newToken = getToken(promptPrefix + promptBodyStr + promptSuffix);
        int newToken = getToken(promptPrefix + promptBodyStr + promptSuffix);
        log.info("新token:{} maxToken:{}", newToken, maxToken);


        while (newToken > maxToken) {
            messageChildHistories.remove(0);

            promptBodyStr = buildPromptBody(messageChildHistories);

            newToken = getToken(promptPrefix + promptBodyStr + promptSuffix);
        }


        MessageHistory newMessageHistory = new MessageHistory();
        newMessageHistory.setPromptBody(messageChildHistories);
        newMessageHistory.setPromptPrefix(promptPrefix);
        newMessageHistory.setPromptBodyStr(promptBodyStr);
        newMessageHistory.setPromptSuffix(promptSuffix);
        return newMessageHistory;
    }


    private MessageHistory buildGroupPrompt(String conversationId, String msg, String finalWxid) {

        MessageHistory messageHistory = getGroupMessageHistory(conversationId);


        if (messageHistory == null) {
            messageHistory = new MessageHistory();
            List<Message> chatRoleChats = new ArrayList<>();
            messageHistory.setCharacter(1);
            messageHistory.setChats(chatRoleChats);
            messageHistory.setIsForbiddenWords(1);
        }

        String nickName = getNickName(messageHistory, finalWxid, conversationId);
        Message chatRoleChat = new Message();
        chatRoleChat.setRole("user");
        chatRoleChat.setContent(StrUtil.format("{}: {}", nickName, msg));

        messageHistory.getChats().add(chatRoleChat);

        String nickNames = getNickNames(messageHistory.getChats());
        String groupPromptPrefix = buildGroupPromptPrefix(nickNames, messageHistory.getCharacter());
        if (StrUtil.isNotEmpty(messageHistory.getGroupPromptPrefix())) {
            groupPromptPrefix = messageHistory.getGroupPromptPrefix();
        }
        messageHistory.setGroupPromptPrefix(groupPromptPrefix);

        Message systemChatRoleChat = new Message();
        systemChatRoleChat.setRole("system");
        systemChatRoleChat.setContent(StrUtil.format(groupPromptPrefix, nickNames, DateUtil.now()));
        messageHistory.getChats().add(0, systemChatRoleChat);


        Message sufffixChatRoleChat = new Message();
        sufffixChatRoleChat.setRole("system");
        String groupPromptSuffix = buildGroupPromptSuffix(messageHistory.getCharacter());
        if (StrUtil.isNotEmpty(messageHistory.getGroupPromptSuffix())) {
            groupPromptSuffix = messageHistory.getGroupPromptSuffix();
        }
        messageHistory.setGroupPromptSuffix(groupPromptSuffix);
        sufffixChatRoleChat.setContent(groupPromptSuffix);
        messageHistory.getChats().add(sufffixChatRoleChat);


        String prompt = messageHistory.getChats().stream().map(Message::getContent).collect(Collectors.joining());

        int newToken = getToken(prompt);
        while (newToken > maxTokenGroup) {
            messageHistory.getChats().remove(1);

            prompt = messageHistory.getChats().stream().map(Message::getContent).collect(Collectors.joining());

            newToken = getToken(prompt);
        }


        return messageHistory;
    }

    private String getNickName(MessageHistory messageHistory, String finalWxid, String conversationId) {

        if (messageHistory.getNickMaps() != null) {
            if (messageHistory.getNickMaps().containsKey(finalWxid)) {
                log.info("成功查找到昵称:{}", messageHistory.getNickMaps().get(finalWxid));
                return messageHistory.getNickMaps().get(finalWxid);
            }
        }
        String nickName = WxUtil.getNickName(finalWxid, conversationId);
        Map<String, String> nickMaps = messageHistory.getNickMaps();
        if (nickMaps == null) {
            nickMaps = new HashMap<>();
        }
        nickMaps.put(finalWxid, nickName);

        messageHistory.setNickMaps(nickMaps);
        return nickName;
    }

    public String getNickNames(List<Message> chatRoleChats) {
        StringBuilder stringBuilder = new StringBuilder();
        if (CollUtil.isEmpty(chatRoleChats)) return "";

        for (Message chatRoleChat : chatRoleChats) {
            if (chatRoleChat.getRole().equals("user")) {
                String content = chatRoleChat.getContent();
                String[] contentSplit = content.split("[:：]");
                if (!stringBuilder.toString().contains(contentSplit[0])) {
                    stringBuilder.append(contentSplit[0] + ",");
                }
            }

        }
        return stringBuilder.toString().substring(0, stringBuilder.toString().length() - 1);
    }


    private String buildPromptBody(List<MessageChildHistory> messageChildHistories) {
        StringBuilder msg = new StringBuilder();

        for (MessageChildHistory messageChildHistory : messageChildHistories) {
            String buildRoleMsg = buildRoleMsg(messageChildHistory.getPrompt());
            msg.append(buildRoleMsg);

            if (StrUtil.isNotEmpty(messageChildHistory.getPromptAnswer())) {
                String buildChatgptMsg = buildChatgptMsg(messageChildHistory.getPromptAnswer());
                msg.append(buildChatgptMsg);
            }
        }
        return msg.toString();
    }


    @NotNull
    private String buildRoleMsg(String msg) {
        return msg + endToken + "\n";
    }

    private String buildChatgptMsg(String msg) {
        return msg + "\n";
    }


    /**
     * 获取历史记录
     *
     * @param conversationId
     * @return
     */
    private MessageHistory getMessageHistory(String conversationId) {
        String redisKey = StrUtil.format(RedisKeyConst.ChatGptMessage, conversationId);
        if (redisTemplate.hasKey(redisKey)) return (MessageHistory) redisTemplate.opsForValue().get(redisKey);
        return null;
    }

    /**
     * 设置历史记录
     *
     * @param conversationId
     * @return
     */
    private void setMessageHistory(String conversationId, MessageHistory messageHistory) {
        String redisKey = StrUtil.format(RedisKeyConst.ChatGptMessage, conversationId);

        log.info("设置:{}", redisKey);
        redisTemplate.opsForValue().set(redisKey, messageHistory, 1, TimeUnit.HOURS);
    }


    /**
     * 获取历史记录
     *
     * @param conversationId
     * @return
     */
    public MessageHistory getGroupMessageHistory(String conversationId) {
        String redisKey = StrUtil.format(RedisKeyConst.GroupChatGptMessage, conversationId);
        if (redisTemplate.hasKey(redisKey)) return (MessageHistory) redisTemplate.opsForValue().get(redisKey);


        return null;
    }

    /**
     * 设置历史记录
     *
     * @param conversationId
     * @return
     */
    private void setGroupMessageHistory(String conversationId, MessageHistory messageHistory) {
        String redisKey = StrUtil.format(RedisKeyConst.GroupChatGptMessage, conversationId);

        log.info("设置:{}", redisKey);
        redisTemplate.opsForValue().set(redisKey, messageHistory, 1, TimeUnit.DAYS);
    }


    /**
     * 删除
     *
     * @param conversationId
     */
    private void removeGroupMessageHistory(String conversationId) {
        String redisKey = StrUtil.format(RedisKeyConst.GroupChatGptMessage, conversationId);
        redisTemplate.delete(redisKey);
    }

    private void removeMessageHistory(String conversationId) {
        String redisKey = StrUtil.format(RedisKeyConst.ChatGptMessage, conversationId);
        redisTemplate.delete(redisKey);
    }


    private Integer getToken(String msg) {
        return gpt2Tokenizer.encode(msg).size();
    }


}
